package com.yesun.dcm.rpc.proxy.jdk;

import com.yesun.dcm.commons.rpc.URL;
import com.yesun.dcm.rpc.Invoker;
import com.yesun.dcm.rpc.proxy.AbstractProxyFactory;
import com.yesun.dcm.rpc.proxy.AbstractProxyInvoker;
import com.yesun.dcm.rpc.proxy.InvokerInvocationHandler;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK代理工厂
 */
public class JdkProxyFactory extends AbstractProxyFactory {

    /**
     * get invoker
     * @param proxy 代理类
     * @param clazz 类型
     * @param url url
     * @param <T>
     * @return
     */
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> clazz, URL url) {
        return new AbstractProxyInvoker<T>(proxy, clazz, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable {
                Method method = proxy.getClass().getMethod(methodName, parameterTypes);
                return method.invoke(proxy, arguments);
            }
        };
    }

    @Override
    public <T> T getProxy(Invoker<T> invoker) {
        Class<?> interfaceClass = invoker.getInterface();
        return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class<?>[]{ interfaceClass }, new InvokerInvocationHandler(invoker));
    }
}
